package com.jingdianjichi.subject.application.config;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.jingdianjichi.subject.application.interceptor.LoginInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;

/**
 * 全局配置类
 *
 * 这个类通过继承WebMvcConfigurationSupport，允许我们自定义Spring MVC的配置。
 * 它主要通过重写configureMessageConverters方法来添加或修改HTTP消息转换器，以满足特定的序列化或反序列化需求。
 *
 * @author: WuYimin
 * Date: 2024-02-06
  */
@Configuration // 表明这是一个配置类，标记后Spring容器会自动识别并加载这个类的配置信息
public class GlobalConfig extends WebMvcConfigurationSupport {

	@Override
	protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
		// 调用父类方法，保留Spring MVC框架默认的消息转换器
		super.configureMessageConverters(converters);
		// 向转换器列表中添加自定义的JSON消息转换器
		converters.add(mappingJackson2HttpMessageConverter());
	}

	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(new LoginInterceptor())
				.addPathPatterns("/**");
	}

	/**
	 * 创建并配置一个 MappingJackson2HttpMessageConverter 实例
	 *
	 * 该方法创建了一个MappingJackson2HttpMessageConverter对象，该对象负责将Java对象序列化为JSON格式的数据，以及将JSON格式的数据反序列化为Java对象。
	 * 通过自定义配置的ObjectMapper，可以实现对序列化和反序列化过程的精细控制，例如，忽略空bean转JSON的错误。
	 *
	 * @return 一个配置好的MappingJackson2HttpMessageConverter实例，用于处理JSON数据的序列化和反序列化
	 */
	private MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
		ObjectMapper objectMapper = new ObjectMapper();
		// 配置ObjectMapper以忽略空bean转JSON的错误，增强容错性
		objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		// 配置 ObjectMapper 在序列化时忽略值为 null 的属性
		objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
		// 利用配置好的ObjectMapper创建MappingJackson2HttpMessageConverter实例
		MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
		return converter;
	}
}
